import { Injectable, BadRequestException } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import {
  CreateVipOrderDto,
  VipOrderResponseDto,
  VipInfoResponseDto,
  CreatePointsOrderDto,
  PointsOrderResponseDto,
  PointsBalanceResponseDto,
  SignInResponseDto,
  SignInRecordDto,
  SignInStatusResponseDto,
} from './dto/vip.dto';

@Injectable()
export class VipService {
  constructor(private readonly prisma: PrismaService) {}

  // VIP套餐配置
  private readonly vipPackages = [
    {
      id: 1,
      name: '月度VIP',
      duration: 30,
      price: 19.99,
      description: '享受30天VIP特权',
    },
    {
      id: 2,
      name: '季度VIP',
      duration: 90,
      price: 49.99,
      description: '享受90天VIP特权，更优惠',
    },
    {
      id: 3,
      name: '年度VIP',
      duration: 365,
      price: 159.99,
      description: '享受365天VIP特权，最优惠',
    },
  ];

  // 积分套餐配置
  private readonly pointsPackages = [
    {
      id: 1,
      name: '60积分',
      points: 60,
      price: 20000,
      //赠送积分
      giftPoints: 18,
      isRecommended: false,
      discount: 0,
    },
    {
      id: 2,
      name: '150积分',
      points: 150,
      price: 50000,
      //赠送积分
      giftPoints: 45,
      isRecommended: true,
      discount: 0,
    },
    {
      id: 3,
      name: '300积分',
      points: 300,
      price: 100000,
      //赠送积分
      giftPoints: 90,
      isRecommended: false,
      discount: 0,
    },
    {
      id: 4,
      name: '600积分',
      points: 600,
      price: 200000,
      //赠送积分
      giftPoints: 180,
      isRecommended: false,
      discount: 0,
    },
    {
      id: 5,
      name: '1500积分',
      points: 1500,
      price: 500000,
      //赠送积分
      giftPoints: 450,
      isRecommended: false,
      discount: 0,
    },
  ];

  async purchaseVip(
    userId: number,
    purchaseDto: CreateVipOrderDto,
  ): Promise<VipOrderResponseDto> {
    const { packageId, paymentMethod } = purchaseDto;

    // 验证套餐
    const vipPackage = this.vipPackages.find((pkg) => pkg.id === packageId);
    if (!vipPackage) {
      throw new BadRequestException('无效的VIP套餐');
    }

    // 生成订单号
    const orderNo = this.generateOrderNo();

    // 计算VIP到期时间（支持续费）
    const now = new Date();
    const user = await this.prisma.user.findUnique({
      where: { id: userId },
      select: { vipExpiredAt: true },
    });

    // 如果用户已经是VIP且未过期，则在现有到期时间基础上延长
    // 如果已过期或不是VIP，则从当前时间开始计算
    const baseTime =
      user?.vipExpiredAt && user.vipExpiredAt > now ? user.vipExpiredAt : now;
    const expiredAt = new Date(
      baseTime.getTime() + vipPackage.duration * 24 * 60 * 60 * 1000,
    );

    // 创建订单记录
    const order = await this.prisma.order.create({
      data: {
        orderNo,
        title: `购买${vipPackage.name}`,
        amount: vipPackage.price,
        status: 'PAID',
        paymentMethod,
        userId,
        remark: `VIP套餐：${vipPackage.name}，时长：${vipPackage.duration}天`,
        expiredAt: new Date(now.getTime() + 24 * 60 * 60 * 1000), // 订单24小时后过期
        metadata: {
          packageId: vipPackage.id,
          packageName: vipPackage.name,
          duration: vipPackage.duration,
          vipExpiredAt: expiredAt,
        },
      },
    });

    // 购买成功后，直接更新用户VIP状态
    await this.prisma.user.update({
      where: { id: userId },
      data: {
        vipExpiredAt: expiredAt,
      },
    });

    return {
      orderId: order.id,
      orderNo: order.orderNo,
      title: order.title,
      amount: Number(order.amount),
      status: order.status,
      paymentMethod: order.paymentMethod,
      packageName: vipPackage.name,
      duration: vipPackage.duration,
      vipExpiredAt: expiredAt.toISOString(),
      createdAt: order.createdAt.toISOString(),
    };
  }

  async getVipInfo(userId: number): Promise<VipInfoResponseDto> {
    const user = await this.prisma.user.findUnique({
      where: { id: userId },
      select: {
        id: true,
        nickname: true,
        vipExpiredAt: true,
        points: true,
      },
    });

    if (!user) {
      throw new BadRequestException('用户不存在');
    }

    const now = new Date();
    const isVip = user.vipExpiredAt && user.vipExpiredAt > now;
    const remainingDays =
      user.vipExpiredAt && user.vipExpiredAt > now
        ? Math.ceil(
            (user.vipExpiredAt.getTime() - now.getTime()) /
              (24 * 60 * 60 * 1000),
          )
        : 0;

    return {
      userId: user.id,
      nickname: user.nickname,
      isVip: isVip || false,
      vipExpiredAt: user.vipExpiredAt?.toISOString() || null,
      remainingDays,
      points: user.points,
    };
  }

  async getVipPackages() {
    return this.vipPackages;
  }

  async purchasePoints(
    userId: number,
    purchaseDto: CreatePointsOrderDto,
  ): Promise<PointsOrderResponseDto> {
    const { packageId, paymentMethod } = purchaseDto;

    // 验证积分套餐
    const pointsPackage = this.pointsPackages.find(
      (pkg) => pkg.id === packageId,
    );
    if (!pointsPackage) {
      throw new BadRequestException('无效的积分套餐');
    }

    // 验证用户是否存在
    const user = await this.prisma.user.findUnique({
      where: { id: userId },
      select: { id: true, nickname: true, points: true },
    });

    if (!user) {
      throw new BadRequestException('用户不存在');
    }

    // 生成订单号
    const orderNo = this.generatePointsOrderNo();

    // 计算实际价格（考虑折扣）
    const actualPrice = pointsPackage.price - pointsPackage.discount;

    // 创建订单记录
    const order = await this.prisma.order.create({
      data: {
        orderNo,
        title: `购买${pointsPackage.name}`,
        amount: actualPrice,
        status: 'PAID',
        paymentMethod,
        userId,
        remark: `积分套餐：${pointsPackage.name}，积分数量：${pointsPackage.points}，原价：${pointsPackage.price}，折扣：${pointsPackage.discount}`,
        expiredAt: new Date(Date.now() + 24 * 60 * 60 * 1000), // 订单24小时后过期
        metadata: {
          packageId: pointsPackage.id,
          packageName: pointsPackage.name,
          points: pointsPackage.points,
          originalPrice: pointsPackage.price,
          discount: pointsPackage.discount,
          actualPrice: actualPrice,
          type: 'POINTS',
        },
      },
    });

    // 购买成功后，直接更新用户积分（包含赠送积分）
    const totalPoints = pointsPackage.points + pointsPackage.giftPoints;
    await this.prisma.user.update({
      where: { id: userId },
      data: {
        points: {
          increment: totalPoints,
        },
      },
    });

    return {
      orderId: order.id,
      orderNo: order.orderNo,
      title: order.title,
      amount: Number(order.amount),
      status: order.status,
      paymentMethod: order.paymentMethod,
      packageName: pointsPackage.name,
      points: totalPoints, // 返回总积分（购买+赠送）
      createdAt: order.createdAt.toISOString(),
    };
  }

  async getPointsPackages() {
    // 计算每个套餐的性价比和实际价格
    return this.pointsPackages.map((pkg) => ({
      ...pkg,
      actualPrice: pkg.price - pkg.discount,
      valueRatio: Math.round(pkg.points / (pkg.price - pkg.discount)),
      savings:
        pkg.discount > 0
          ? `${Math.round((pkg.discount / pkg.price) * 100)}%`
          : null,
    }));
  }

  // 获取推荐积分套餐
  async getRecommendedPointsPackages() {
    const packages = await this.getPointsPackages();
    return packages.filter((pkg) => pkg.isRecommended);
  }

  // 获取积分套餐统计信息
  async getPointsPackagesStats() {
    const packages = await this.getPointsPackages();
    const totalPoints = packages.reduce((sum, pkg) => sum + pkg.points, 0);
    const totalPrice = packages.reduce(
      (sum, pkg) => sum + (pkg.price - pkg.discount),
      0,
    );
    const avgValueRatio = Math.round(totalPoints / totalPrice);

    return {
      totalPackages: packages.length,
      totalPoints,
      totalPrice,
      averageValueRatio: avgValueRatio,
      recommendedPackages: packages.filter((pkg) => pkg.isRecommended).length,
    };
  }

  // 获取用户积分余额
  async getPointsBalance(userId: number): Promise<PointsBalanceResponseDto> {
    const user = await this.prisma.user.findUnique({
      where: { id: userId },
      select: {
        id: true,
        nickname: true,
        points: true,
        updatedAt: true,
      },
    });

    if (!user) {
      throw new BadRequestException('用户不存在');
    }

    return {
      points: user.points,
    };
  }

  // 模拟支付成功回调（实际项目中应该由支付平台调用）
  async handlePaymentSuccess(
    orderId: string,
    paymentNo: string,
  ): Promise<void> {
    const order = await this.prisma.order.findUnique({
      where: { id: orderId },
    });

    if (!order) {
      throw new BadRequestException('订单不存在');
    }

    if (order.status !== 'PENDING') {
      throw new BadRequestException('订单状态不正确');
    }

    // 更新订单状态为已支付
    await this.prisma.order.update({
      where: { id: orderId },
      data: {
        status: 'PAID',
        paymentTime: new Date(),
        paymentNo,
      },
    });

    // 更新用户VIP状态
    const metadata = order.metadata as any;
    if (metadata && metadata.vipExpiredAt && order.userId) {
      await this.prisma.user.update({
        where: { id: order.userId },
        data: {
          vipExpiredAt: new Date(metadata.vipExpiredAt),
        },
      });
    }
  }

  // 处理VIP续费逻辑（如果用户已经是VIP，则在现有到期时间基础上延长）
  async handleVipRenewal(userId: number, packageId: number): Promise<void> {
    const user = await this.prisma.user.findUnique({
      where: { id: userId },
      select: { vipExpiredAt: true },
    });

    if (!user) {
      throw new BadRequestException('用户不存在');
    }

    const vipPackage = this.vipPackages.find((pkg) => pkg.id === packageId);
    if (!vipPackage) {
      throw new BadRequestException('无效的VIP套餐');
    }

    const now = new Date();
    // 如果用户已经是VIP且未过期，则在现有到期时间基础上延长
    // 如果已过期或不是VIP，则从当前时间开始计算
    const baseTime =
      user.vipExpiredAt && user.vipExpiredAt > now ? user.vipExpiredAt : now;
    const newExpiredAt = new Date(
      baseTime.getTime() + vipPackage.duration * 24 * 60 * 60 * 1000,
    );

    await this.prisma.user.update({
      where: { id: userId },
      data: {
        vipExpiredAt: newExpiredAt,
      },
    });
  }

  private generateOrderNo(): string {
    const timestamp = Date.now().toString();
    const random = Math.floor(Math.random() * 1000)
      .toString()
      .padStart(3, '0');
    return `VIP${timestamp}${random}`;
  }

  private generatePointsOrderNo(): string {
    const timestamp = Date.now().toString();
    const random = Math.floor(Math.random() * 1000)
      .toString()
      .padStart(3, '0');
    return `PTS${timestamp}${random}`;
  }

  // 用户签到
  async signIn(userId: number): Promise<SignInResponseDto> {
    const today = new Date();
    const todayStart = new Date(
      today.getFullYear(),
      today.getMonth(),
      today.getDate(),
    );
    const todayEnd = new Date(todayStart.getTime() + 24 * 60 * 60 * 1000 - 1);

    // 检查今日是否已签到
    const existingSignIn = await this.prisma.userSignIn.findFirst({
      where: {
        userId,
        signInDate: {
          gte: todayStart,
          lte: todayEnd,
        },
      },
    });

    if (existingSignIn) {
      throw new BadRequestException('今日已签到，请明天再来！');
    }

    // 获取用户最后一次签到记录
    const lastSignIn = await this.prisma.userSignIn.findFirst({
      where: { userId },
      orderBy: { signInDate: 'desc' },
    });

    // 计算连续签到天数
    let continuous = 1;
    if (lastSignIn) {
      const lastSignInDate = new Date(lastSignIn.signInDate);
      const lastSignInStart = new Date(
        lastSignInDate.getFullYear(),
        lastSignInDate.getMonth(),
        lastSignInDate.getDate(),
      );
      const yesterdayStart = new Date(
        todayStart.getTime() - 24 * 60 * 60 * 1000,
      );

      if (lastSignInStart.getTime() === yesterdayStart.getTime()) {
        continuous = lastSignIn.continuous + 1;
      }
    }

    // 计算签到积分（基础积分 + 连续签到奖励）
    const basePoints = 10;
    const continuousBonus = Math.min(continuous * 2, 20); // 连续签到奖励，最多20积分
    const totalPoints = basePoints + continuousBonus;

    // 创建签到记录
    const signIn = await this.prisma.userSignIn.create({
      data: {
        userId,
        signInDate: today,
        points: totalPoints,
        continuous,
      },
    });

    // 创建积分记录
    await this.prisma.signInPointsRecord.create({
      data: {
        userId,
        signInId: signIn.id,
        points: totalPoints,
        reason: `每日签到${continuous > 1 ? `，连续${continuous}天` : ''}`,
      },
    });

    // 更新用户积分
    await this.prisma.user.update({
      where: { id: userId },
      data: {
        points: {
          increment: totalPoints,
        },
      },
    });

    // 生成签到消息
    let message = `签到成功！获得${totalPoints}积分`;
    if (continuous > 1) {
      message += `，已连续签到${continuous}天`;
    }
    if (continuous >= 7) {
      message += '，太棒了！';
    }

    return {
      id: signIn.id,
      userId: signIn.userId,
      signInDate: signIn.signInDate.toISOString(),
      points: signIn.points,
      continuous: signIn.continuous,
      message,
      createdAt: signIn.createdAt.toISOString(),
    };
  }

  // 获取用户签到记录列表
  async getSignInList(userId: number): Promise<SignInRecordDto[]> {
    const signIns = await this.prisma.userSignIn.findMany({
      where: { userId },
      orderBy: { signInDate: 'desc' },
      take: 30, // 最近30天
      include: {
        signInPointsRecords: {
          select: {
            reason: true,
          },
        },
      },
    });

    return signIns.map((signIn) => ({
      id: signIn.id,
      signInDate: signIn.signInDate.toISOString(),
      points: signIn.points,
      continuous: signIn.continuous,
      reason: signIn.signInPointsRecords[0]?.reason || '每日签到',
      createdAt: signIn.createdAt.toISOString(),
    }));
  }

  // 获取用户今日签到状态
  async getSignInStatus(userId: number): Promise<SignInStatusResponseDto> {
    const today = new Date();
    const todayStart = new Date(
      today.getFullYear(),
      today.getMonth(),
      today.getDate(),
    );
    const todayEnd = new Date(todayStart.getTime() + 24 * 60 * 60 * 1000 - 1);
    const monthStart = new Date(today.getFullYear(), today.getMonth(), 1);

    // 检查今日是否已签到
    const todaySignIn = await this.prisma.userSignIn.findFirst({
      where: {
        userId,
        signInDate: {
          gte: todayStart,
          lte: todayEnd,
        },
      },
    });

    // 获取连续签到天数
    const lastSignIn = await this.prisma.userSignIn.findFirst({
      where: { userId },
      orderBy: { signInDate: 'desc' },
    });

    let continuousDays = 0;
    if (lastSignIn) {
      const lastSignInDate = new Date(lastSignIn.signInDate);
      const lastSignInStart = new Date(
        lastSignInDate.getFullYear(),
        lastSignInDate.getMonth(),
        lastSignInDate.getDate(),
      );
      const yesterdayStart = new Date(
        todayStart.getTime() - 24 * 60 * 60 * 1000,
      );

      if (lastSignInStart.getTime() === yesterdayStart.getTime()) {
        continuousDays = lastSignIn.continuous;
      } else if (lastSignInStart.getTime() === todayStart.getTime()) {
        continuousDays = lastSignIn.continuous;
      }
    }

    // 获取本月签到天数
    const monthSignIns = await this.prisma.userSignIn.count({
      where: {
        userId,
        signInDate: {
          gte: monthStart,
        },
      },
    });

    // 计算下次签到时间
    const nextSignInTime = new Date(todayStart.getTime() + 24 * 60 * 60 * 1000);

    // 生成签到提醒
    let message = '记得每天签到哦！';
    if (continuousDays > 0) {
      message = `已连续签到${continuousDays}天，继续加油！`;
    }
    if (continuousDays >= 7) {
      message += `太棒了！已连续签到${continuousDays}天，保持这个好习惯！`;
    }

    return {
      userId,
      todaySignedIn: !!todaySignIn,
      continuousDays,
      monthSignInDays: monthSignIns,
      todaySignInTime: todaySignIn ? todaySignIn.createdAt.toISOString() : null,
      nextSignInTime: nextSignInTime.toISOString(),
      message,
    };
  }
}
